import { Directive, Input, Output, EventEmitter, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { assign as _assign } from 'lodash';
import { LvSortDirection as SortDirection, LvPureSortDirection as PureSort, LvConfig } from '../core/api';
import { BaseSortConfig, SortConfig } from './interface';

@Directive({
  selector: '[lvSort], [lv-sort]',
  exportAs: 'lvSort',
})
export class SortDirective implements OnChanges, OnDestroy {
  @Input() lvActiveSort: BaseSortConfig; // 指定当前的排序
  @Input() lvDefaultSort: PureSort = 'asc'; // 默认初始化排序
  @Output() lvActiveSortChange = new EventEmitter<BaseSortConfig>();
  // @Input() sortMode: 'single' | 'multiple' = 'single'; // 单列排序、多列排序 只支持单列
  @Output() lvSortChange = new EventEmitter<SortConfig | SortConfig[]>();
  // 输入输出属性
  @Input() lvDisableSortClear =
    LvConfig.dataTableOptions.lvDisableSortClear !== undefined ? LvConfig.dataTableOptions.lvDisableSortClear : false; // 是否禁用清除排序

  // 外部可访问变量
  key: string;
  direction: SortDirection;

  // 内部变量
  _sortsFactor = new Map<string, SortConfig>();
  _stateChange = new BehaviorSubject<void>(null);
  private _activeSort: BaseSortConfig;

  constructor() {}

  clear(): void {
    this._emitSortChange();
  }

  ngOnDestroy(): void {
    this._stateChange.complete();
  }

  _updateDirection(value: BaseSortConfig): void {
    this._activeSort = value;
    const _value = value || {};
    this.key = _value.key;
    this.direction = _value.direction;
  }

  ngOnChanges(changes: SimpleChanges): void {
    const activeSortChange = changes.lvActiveSort;
    if (activeSortChange) {
      this._updateDirection(activeSortChange.currentValue);
    }
    this._stateChange.next(null);
  }

  sort(source: SortConfig): void {
    if (source.key === this.key) {
      this.direction = this.getNextDirection(source);
    } else {
      this.key = source.key;
      this.direction = source.defaultSort || this.lvDefaultSort;
    }

    this._emitSortChange({
      key: source.key,
      direction: this.direction,
      customSort: source.customSort,
    });
  }

  // 下一个排序方向
  getNextDirection(source: SortConfig): SortDirection {
    const directions: SortDirection[] = ['asc', 'desc'];
    const _disableSortClear = source.disableSortClear === undefined ? this.lvDisableSortClear : source.disableSortClear;

    if ((source.defaultSort || this.lvDefaultSort) === 'desc') {
      directions.reverse();
    }

    if (!_disableSortClear) {
      directions.push('');
    }

    const { length } = directions;
    const preIndex = directions.indexOf(this.direction || '');
    const currentIndex = preIndex + 1 >= length ? 0 : preIndex + 1;

    return directions[currentIndex];
  }

  _emitSortChange(source?: { [key: string]: any }): void {
    let _source;
    let data;

    if (source) {
      _source = { ...source, ...{ key: source.key, direction: source.direction } };
    }

    if (_source && _source.direction === '') {
      _source.key = '';
    }

    if (this._activeSort) {
      delete this._activeSort.direction;
      delete this._activeSort.key;
    }

    // 保证不改变地址，避免地址变化触发一次change
    data = this._activeSort ? _assign(this._activeSort, _source) : _source;

    this._updateDirection(data);
    this.lvActiveSortChange.emit(this._activeSort);
    this.lvSortChange.emit(_source);
  }
}
